home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-05-02 | 78.4 KB | 1,818 lines | [TEXT/CWIE] |
- /*
- ** TransSkel++.cp
- **
- ** The TransSkel++ module provides a C++ interface to Paul
- ** Dubois' TransSkel Application Skeleton. With TransSkel++,
- ** much of the object-oriented flavor of the TransSkel
- ** module is massaged into a simple and extendable class
- ** framework. With not too much fuss, users of TransSkel++
- ** may create menus, windows, dialogs, and even applications
- ** in as intuitive a way as C++ will allow.
- **
- ** Compiles under Symantec C/C++ 7.0.4
- ** Metrowerks C/C++ 8
- ** Uses TransSkel v3.24
- **
- ** Fred Dushin
- ** email: fadushin@top.cis.syr.edu
- **
- ** Release 3.04 May 1, 1996 "Dyslexics untie!"
- ** See release notes for details of changes.
- */
-
- #include <TransSkel++.h>
-
- //----------------------------------------------------------------------/
- // internal headers /
- //----------------------------------------------------------------------/
-
- //----------------------------------------------------------------------/
- // Headers for the mini-list manager /
- // Supports: Dynamic creation and destruction of lists /
- // via traditional "cons" cells. /
- //----------------------------------------------------------------------/
-
- typedef void * elt;
- typedef struct consCell{
- elt carPtr;
- struct consCell *cdrPtr;
- } consCell, *list;
- #define car(l) ((l)->carPtr)
- #define cdr(l) ((l)->cdrPtr)
-
- // A predPtr is a pointer to a predicate (funtion), used as
- // a callback for finding items in a list
-
- typedef Boolean (*predPtr)( void * item, void * predParams );
- static Boolean hasID( void *item, void *predParams );
- static Boolean isThis( void *item, void *predParams );
-
- // list manager function prototypes
-
- static list cons( elt head,elt tail );
- static elt findOne( predPtr pred, void * predParams, list l );
- static list removeItem( elt item, list l );
- static void DestroyCons( consCell * c );
- static void DestroyList( list l );
-
- //----------------------------------------------------------------------/
- // A menuStruct is merely a menuID and a pointer to /
- // the CMenuObj class instance associated with the menuID. /
- // TransSkel++ maintains a list of menuStructs as menus /
- // are created and destroyed. These structs are themselves /
- // dynamically created and deleted. /
- //----------------------------------------------------------------------/
-
- typedef struct menuStruct{
- short menuID;
- CMenuObj *menu;
- } menuStruct;
-
- //----------------------------------------------------------------------/
- // The menuList is the list of all menuStructs created /
- // sApplication is a pointer to the only application /
- // sAppleMenu is a pointer to the (ONLY) apple menu /
- // /
- // appleApplItems is a flag from Paul's SkelApple.c module /
- // It is set to true when the user defines an application /
- // item in the apple menu; o/w it remains false. /
- // DoAppleMenu is lifted directly from SkelApple. It's /
- // defined here and called in place of Paul's corresponding function /
- // so that Apple menu items are properly handled. /
- // DoMenuCommand is a hack of Paul's function by the same name /
- //----------------------------------------------------------------------/
-
- static list menuList = nil;
- static CApplication *sApplication = nil;
- static CMenuObj *sAppleMenu = nil;
- static Boolean appleApplItems = false;
- static pascal void DoAppleMenu( short menuID, short item );
- static Boolean DoMenuCommand( long command );
-
- //----------------------------------------------------------------------/
- // The SkelppWindowPropertyID is used to retrieve a structure /
- // used internally by TransSkel++. The structure includes a /
- // pointer to a CApplObj, ostensibly the CWindow or CDialog /
- // class instance associated with the window or dialog. /
- // The class instances typically get retrieved in the TransSkel /
- // callbacks in order to call the appropriate class methods. /
- //----------------------------------------------------------------------/
-
- #define OFFSET 2704
- enum{
- SkelppWindowPropertyID = skelWPropApplBase + OFFSET
- };
- typedef struct SkelppWindowProperty{
- CApplObj *obj;
- // Additional fields for future use (?)
- } SkelppWindowProperty;
-
-
- /*---------------------------------------------------------------------*/
- /* TransSkel callbacks */
- /* */
- /* These "C" functions get passed to TransSkel and get */
- /* called at the appropriate events. Except where noted, */
- /* most callbacks defined here merely call the methods */
- /* of the appropriate class instance, though typically, */
- /* these methods will be over-ridden in sub-class definitions. */
- /*---------------------------------------------------------------------*/
-
- extern "C"{
-
- // CApplication callbacks
- static pascal void _doSuspendResume(Boolean inForeground);
- static pascal void _doIdle( void );
- static pascal Boolean _doEventHook(EventRecord *evt);
- static pascal void _doAE(EventRecord *evt);
-
- // CMenu callbacks
- static pascal void _doMenuClobber(MenuHandle menu);
-
- // CAppleMenu callbacks
- static pascal void _doAppleSelect( short item );
- static pascal void _doAppleClobber(MenuHandle menu);
-
- // CWindow callbacks
- static pascal void _doWindowMouseClick(Point where, long when, short modifiers);
- static pascal void _doWindowKeyClick(short c, short code, short modifiers);
- static pascal void _doWindowUpdate (Boolean resized);
- static pascal void _doWindowActivate (Boolean active);
- static pascal void _doWindowClose(void);
- static pascal void _doWindowClobber(void);
- static pascal void _doWindowIdle (void);
-
- // CDialog callbacks
- static pascal Boolean _doDialogFilter(DialogPtr dlog, EventRecord *evt, short *item);
- static pascal void _doDialogSelect(DialogPtr dlog, short item);
- static pascal void _doDialogClose(void);
- static pascal void _doDialogClobber(void);
-
- }
-
-
- //----------------------------------------------------------------------/
- // implementation /
- //----------------------------------------------------------------------/
-
-
- //======================================================================/
- // The CApplObj Class /
- // /
- // Base Class: none /
- // Methods: • Error(Str255 errorStr, short code); /
- // Handle errors in TransSkel++ /
- // /
- // Description: Every class in TransSkel++ is a subclass /
- // of the ApplObj base class. This permits all objects /
- // to inherit the error handling facilities defined therein. /
- //======================================================================/
-
-
- //----------------------------------------------------------------------/
- // Error protected /
- // /
- // Default error handling method. Calls fatalAlert if fatal error /
- // message passed in error code, then exits program _abnorammly_ /
- // /
- // PARAMETERS /
- // errorStr: a pascal string when gets printed in alert box /
- // code: an error code /
- // RETURN VALUE /
- // none /
- //----------------------------------------------------------------------/
-
- void
- CApplObj::Error( Str255 errorStr, short code )
- {
-
- switch( code ){
- case Skelpp_noErr:
- break;
- case Skelpp_fatalErr:
- FatalAlert( errorStr );
- ExitToShell();
- break;
- }
-
- }
-
-
- //----------------------------------------------------------------------/
- // FatalAlert private /
- // /
- // Put up an internally defined alert after beeping. Also puts up /
- // exit button in alert box and message telling about to exit /
- // /
- // PARAMETERS /
- // str: a pascal string when gets printed in alert box /
- // RETURN VALUE /
- // none /
- //----------------------------------------------------------------------/
-
- void
- CApplObj::FatalAlert( Str255 str )
- {
- SysBeep( 10 );
- FakeAlert( str, "\p\r\r", "\pPress Exit to quit program\r", nil,
- 1, 1, 0, "\pExit", nil, nil );
- }
-
-
- //======================================================================/
- // The CApplication Class /
- // /
- // Base Class: CApplObj Class /
- // Methods: • Run(void); /
- // Run the application /
- // • doEventHook(EventRecord *evt); /
- // Respect the host's event hook /
- // • doSuspendResume(Boolean inForeground); /
- // Handle suspend/resume events /
- // • doIdle(void); /
- // Handle idle events /
- // /
- // Description: Every program must have exactly one CApplication /
- // class (or subclass) instance, which is pointed to by the static /
- // pointer sApplication. Typically, a programmer will define /
- // a subclass of the CApplication class for his or her purposes, /
- // making it a container for all global storage in the program. /
- // /
- // The CApplication class constructor adds an event hook for /
- // inspecting events before being processed by TransSkel. This /
- // event hook is necessary for proper handling of menu events, /
- // since TransSkel does not have anything for menus like the /
- // property list it supports for windows and dialogs. /
- //======================================================================/
-
-
- //----------------------------------------------------------------------/
- // CApplication public /
- // /
- // The CApplication constructor Initializes TransSkel /
- // and registers the idle, suspend/resume, and event hook /
- // procedures mentioned above. A pointer to the application /
- // is initialized to the (sole) instance of this class. /
- // This pointer is needed in order for TransSkel++ to call /
- // the class's methods. /
- // /
- // PARAMETERS /
- // initParams: initialization parameters passed to SkelInit /
- // RETURN VALUE /
- // none /
- //----------------------------------------------------------------------/
-
- CApplication::CApplication( SkelInitParamsPtr initParams )
- {
- if ( !sApplication ){
- SkelInit( initParams );
-
- // Set up internal callbacks
- SkelSetIdle( _doIdle );
- SkelSetSuspendResume( _doSuspendResume );
- SkelSetEventHook( _doEventHook );
- if ( SkelQuery( skelQHasAppleEvents ) ){
- SkelSetAEHandler( _doAE );
- }
- sApplication = this;
- }
- else{
- Error("\pYou may only define one application", Skelpp_fatalErr);
- }
- }
-
-
- //----------------------------------------------------------------------/
- // ~CApplication public /
- // /
- // The CApplication destructor. /
- // Calls SkelCleanup() and sets the global sApplication to nil /
- // (in the unlikely event host defines a new application). /
- // /
- // PARAMETERS /
- // none /
- // RETURN VALUE /
- // none /
- //----------------------------------------------------------------------/
-
- CApplication::~CApplication(void)
- {
- SkelCleanup();
- sApplication = nil;
- }
-
-
- /*---------------------------------------------------------------------*/
- /* TransSkel callbacks for CApplication class */
- /* */
- /* These "C" functions get passed to TransSkel and get */
- /* called at the appropriate events. Except where noted, */
- /* most callbacks defined here merely call the methods */
- /* of the appropriate class instance, though typically, */
- /* these methods will be over-ridden in sub-class definitions. */
- /*---------------------------------------------------------------------*/
-
- extern "C"{
-
- /*---------------------------------------------------------------------*/
- /* _doSuspendResume static */
- /* */
- /* Call the application's suspend/resume method */
- /* */
- /* PARAMETERS */
- /* as per TransSkel */
- /* RETURN VALUE */
- /* as per TransSkel */
- /*---------------------------------------------------------------------*/
-
- static pascal void
- _doSuspendResume( Boolean inForeground )
- {
- if ( sApplication ){
- sApplication->doSuspendResume( inForeground );
- }
- }
-
-
- /*---------------------------------------------------------------------*/
- /* _doIdle static */
- /* */
- /* Call the application's idle method */
- /* */
- /* PARAMETERS */
- /* as per TransSkel */
- /* RETURN VALUE */
- /* as per TransSkel */
- /*---------------------------------------------------------------------*/
-
- static pascal void
- _doIdle(void)
- {
- if ( sApplication ){
- sApplication->doIdle();
- }
- }
-
-
- /*---------------------------------------------------------------------*/
- /* _doEventHook static */
- /* */
- /* Inspect the event before TransSkel has a chance to. */
- /* If there was a mouseDown event in the menubar or a */
- /* command key equivalent, process the event by */
- /* doing a menu(Select|Key) and calling the doSelect */
- /* method in the menu class instance in the menuList. */
- /* This is necessary because TransSkel provides no way */
- /* of informing the callbacks for the menu handlers of */
- /* the menu being invoked; nor are there menu property */
- /* lists, as there are for windows and dialogs. */
- /* */
- /* PARAMETERS */
- /* as per TransSkel */
- /* RETURN VALUE */
- /* as per TransSkel */
- /*---------------------------------------------------------------------*/
-
- static pascal Boolean
- _doEventHook(EventRecord *evt)
- {
- Boolean result = false;
-
- if ( !sApplication )
- return false;
-
- /* First, respect the host's event hook */
- if ( sApplication->doEventHook( evt ) ){
- return true;
- }
-
- /* otherwise, check for menu events */
- switch ( evt->what ){
- case mouseDown:
- GrafPtr evtPort;
- short evtPart;
- Rect appleRect;
-
- evtPart = FindWindow ( evt->where, &evtPort );
-
- if ( evtPart == inMenuBar ){
- /* First call the CApplication's menu hook */
- sApplication->doMenuHook();
- /* Then handle the menu command */
- result = DoMenuCommand( MenuSelect( evt->where ) );
- }
- break;
-
- case keyDown:
- case autoKey:
- char evtChar = evt->message & charCodeMask;
-
- if ( (evt->modifiers & cmdKey) && !SkelCmdPeriod ( evt ) ){
- sApplication->doMenuHook();
- result = DoMenuCommand( MenuKey( evtChar ) );
- }
- break;
- }
- return result;
- }
-
-
- /*---------------------------------------------------------------------*/
- /* _doAE static */
- /* */
- /* Call the application's AE method */
- /* */
- /* PARAMETERS */
- /* as per TransSkel */
- /* RETURN VALUE */
- /* as per TransSkel */
- /*---------------------------------------------------------------------*/
-
- static pascal void
- _doAE( EventRecord *evt )
- {
- if ( sApplication ){
- sApplication->doAE( evt );
- }
- }
-
- } /* extern "C" */
-
-
-
- //----------------------------------------------------------------------/
- // DoMenuCommand static /
- // /
- // This definition is adapted from the TransSkel static function by the /
- // same name. It's needed here in order to handle selection of items /
- // in the apple menu properly. /
- // /
- // PARAMETERS /
- // command: encodes menu/item in long /
- // RETURN VALUE /
- // true if a menu was handles; false o/w /
- //----------------------------------------------------------------------/
-
- static Boolean
- DoMenuCommand( long command )
- {
- short menuID, item;
- Boolean result = false;
- menuStruct * theMenu;
-
- menuID = HiWord( command );
- item = LoWord( command );
-
- /* find the menuStruct in menuList which has menuID */
- theMenu = (menuStruct *)findOne( hasID, &menuID, menuList );
- if ( theMenu ){
- /* Treat Apple menu specially (Because of 'DRVR' resources) */
- if ( menuID == skelAppleMenuID ){
- DoAppleMenu( menuID, item );
- }
- else{
- theMenu->menu->doSelect( item );
- }
- result = true;
- }
- HiliteMenu( 0 );
- return result;
- }
-
-
- //----------------------------------------------------------------------/
- // DoAppleMenu static /
- // /
- // Paul's DoAppleItem proc, with minor modification /
- // This is lifted directly from SkelApple.c. /
- // /
- // PARAMETERS /
- // menuID: menu ID of apple menu (should be 128) /
- // item: menu item selected /
- // RETURN VALUE /
- // true if a menu was handles; false o/w /
- //----------------------------------------------------------------------/
-
- static pascal void
- DoAppleMenu( short menuID, short item )
- {
- GrafPtr curPort;
- Str255 str;
- Handle h;
- short i;
- MenuHandle menu = GetMHandle(menuID);
-
- /*
- * If there are application items, determine if item is one of them.
- * Can tell by tracking backward through the items; if the gray line
- * separating application items and DA's if not found before top of
- * menu is reached, then its an application item, else a DA. This
- * strategy requires that there be no "-" items in the items string
- * passed to SkelApple().
- */
- if ( appleApplItems )
- {
- for (i = item; i > 0; i--) /* look from current to item 1 */
- {
- GetItem (menu, i, str);
- if (str[0] == 1 && str[1] == '-')
- break;
- }
- if (i == 0) /* reached top without seeing line */
- {
- _doAppleSelect(item);
- return;
- }
- }
-
- /* either no application items or selection isn't one of them */
- GetPort (&curPort);
- GetItem(menu, item, str); /* get DA name */
- SetResLoad (false);
- h = GetNamedResource ('DRVR', str);
- SetResLoad (true);
- if (h != (Handle) nil)
- {
- #if skelUnivHeaders
- ReserveMem (GetResourceSizeOnDisk (h) + 0x1000);
- #else
- /* can't use new name for this one in non-universal headers */
- ReserveMem (SizeResource (h) + 0x1000);
- #endif
- (void) OpenDeskAcc (str); /* open it */
- }
- SetPort (curPort);
- }
-
-
- //----------------------------------------------------------------------/
- // hasID static /
- // /
- // List handler callback /
- // /
- // PARAMETERS /
- // item: current item on list /
- // predParams: parameter passed through list handler /
- // RETURN VALUE /
- // true if item has same id as that passed through predParames; /
- // false, o/w /
- //----------------------------------------------------------------------/
-
- static Boolean
- hasID(void *item, void *predParams)
- {
- return( ((menuStruct *)item)->menuID == *(short *)predParams );
- }
-
-
- //----------------------------------------------------------------------/
- // isThis static /
- // /
- // List handler callback /
- // /
- // PARAMETERS /
- // item: current item on list /
- // predParams: parameter passed through list handler /
- // RETURN VALUE /
- // true if item is the same as that passed through predParames; /
- // false, o/w /
- //----------------------------------------------------------------------/
-
- static Boolean
- isThis(void *item, void *predParams)
- {
- return( ((menuStruct *)item)->menu == (CMenuObj *)predParams );
- }
-
-
-
- //======================================================================/
- // The CMenu Class /
- // /
- // Base Class: CMenuObj Class /
- // Methods: • doSelect(short item); /
- // Handle item selections in menu /
- // /
- // Member variables: /
- // • MenuHandle menu; (protected) /
- // A handle to the QD menu structure /
- // /
- // Description: The CMenu class is used for standard (anything /
- // not an apple) menu handling. Users of TransSkel++ will typically /
- // create subclasses of the CMenu class for each menu in the /
- // application (e.g., CFileMenu, CEditMenu, etc.) Because TransSkel /
- // treates the Apple menu specially, a special CAppleMenu class /
- // is defined below. /
- //======================================================================/
-
-
- //----------------------------------------------------------------------/
- // CMenu public /
- // /
- // The CMenu constructor. /
- // /
- // PARAMETERS /
- // menuID: resource id of new menu /
- // subMenu: true if is a submenu /
- // drawBar: draw the menubar after creation (usually false) /
- // RETURN VALUE /
- // none /
- //----------------------------------------------------------------------/
-
- CMenu::CMenu( short menuID, Boolean subMenu, Boolean drawBar )
- {
- menuStruct *ms;
-
- // Create the menu
- menu = GetMenu( menuID );
- if ( !menu ){
- Error( "\pCould not allocate memory for menu", Skelpp_fatalErr );
- return;
- }
-
- // register it with TransSkel
- if ( !SkelMenu( menu,
- nil, /* item selection handler */
- nil, /* disposal function */
- subMenu, /* true if hierarchichal */
- drawBar ) /* true if draw after alloc'd */
- ){
- Error( "\pCould not register menu with TransSkel",
- Skelpp_fatalErr );
- DisposeMenu( menu );
- return;
- }
-
- // Create a menuStruct to hold menuID and pointer to class instance
- if ( !(ms = (menuStruct *)NewPtr( sizeof( menuStruct ) )) ){
- Error( "\pCould not allocate internal menu list handler",
- Skelpp_fatalErr );
- DisposeMenu( menu );
- return;
- }
-
- // intitialize fields and place on menuList
- ms->menuID = menuID;
- ms->menu = this;
- menuList = cons( ms, menuList );
- }
-
-
- //----------------------------------------------------------------------/
- // ~CMenu public /
- // /
- // The CMenu destructor. /
- // First get rid of the menuStruct on the menuList, if it exists /
- // Then call SkelRmveWindow, which deletes the menu from the /
- // menubar, redraws the menubar, and then calls the clobber /
- // proc for the menu, which in this case will be _doMenuClobber /
- // (which frees space tied up by menu). This is safe, /
- // assuming the user has not called SkelRmveMenu or SkelCleanup /
- // _before_ deleting the menu instance. /
- // /
- // PARAMETERS /
- // none /
- // RETURN VALUE /
- // none /
- //----------------------------------------------------------------------/
-
- CMenu::~CMenu(void)
- {
- menuStruct *ms;
-
- ms = (menuStruct *)findOne( isThis, this, menuList );
- if ( ms ){
- menuList = removeItem( ms , menuList );
- DisposePtr( (Ptr)ms );
- }
- SkelRmveMenu( menu );
- DisposeMenu( menu );
- }
-
-
- /*---------------------------------------------------------------------*/
- /* TransSkel callbacks for CMenu class */
- /* */
- /* These "C" functions get passed to TransSkel and get */
- /* called at the appropriate events. Except where noted, */
- /* most callbacks defined here merely call the methods */
- /* of the appropriate class instance, though typically, */
- /* these methods will be over-ridden in sub-class definitions. */
- /*---------------------------------------------------------------------*/
-
- extern "C"{
-
- /*---------------------------------------------------------------------*/
- /* _doMenuClobber static */
- /* */
- /* For future use */
- /* */
- /* PARAMETERS */
- /* as per TransSkel */
- /* RETURN VALUE */
- /* as per TransSkel */
- /*---------------------------------------------------------------------*/
-
- static pascal void
- _doMenuClobber( MenuHandle menu ){}
-
- } /* extern "C" */
-
-
- //======================================================================/
- // The CAppleMenu Class /
- // /
- // Base Class: CMenuObj Class /
- // Methods: • doSelect(short item); /
- // Handle item selections in Apple menu /
- // /
- // Description: The CAppleMenu class is used for managing the /
- // apple menu. Because TransSkel treats the apple menu specially, /
- // (with SkelApple), a special class constructor is needed. Also, /
- // TransSkel provides for no destructors for Apple menus, so /
- // the CAppleMenu class has no clobber method. /
- //======================================================================/
-
-
- //----------------------------------------------------------------------/
- // CAppleMenu public /
- // /
- // The CAppleMenu constructor. /
- // /
- // PARAMETERS /
- // items: Pascal String for about menu item(s) /
- // RETURN VALUE /
- // none /
- //----------------------------------------------------------------------/
-
- CAppleMenu::CAppleMenu( const StringPtr items )
- {
- menuStruct *ms;
-
- /* 024 = apple character */
- menu = NewMenu( skelAppleMenuID, (StringPtr) "\p\024" );
- if (items != (StringPtr) nil && items[0] > 0)
- {
- /* application has own items in menu */
- appleApplItems = true;
- /* add items */
- AppendMenu( menu, items );
- /* add gray line */
- AppendMenu( menu, (StringPtr) "\p(-" );
- }
- AddResMenu( menu, 'DRVR' ); /* add desk accessories */
- (void) SkelMenu ( menu, _doAppleSelect, _doAppleClobber,
- false, false );
-
- if ( !sAppleMenu ){
- if ( !(ms = (menuStruct *)NewPtr( sizeof( menuStruct ) )) ){
- Error( "\pCould not allocate internal menu list handler",
- Skelpp_fatalErr );
- DisposeMenu( menu );
- return;
- }
-
- ms->menuID = 128;
- ms->menu = this;
- menuList = cons( ms, menuList );
- sAppleMenu = this;
- }
- else{
- Error( "\pYou may only have one apple menu",
- Skelpp_fatalErr );
- }
- }
-
-
- //----------------------------------------------------------------------/
- // ~CAppleMenu public /
- // /
- // The CAppleMenu destructor. /
- // First get rid of the menuStruct on the menuList, if it exists, /
- // and restore globals to their original state (just in case /
- // user decides to make a new apple menu on-the-fly). /
- // Then call SkelRmveWindow, which deletes the menu from the /
- // menubar, redraws the menubar, and then calls the clobber /
- // proc for the menu, which in this case will be _doAppleClobber /
- // (which frees space tied up by menu) /
- // /
- // PARAMETERS /
- // none /
- // RETURN VALUE /
- // none /
- //----------------------------------------------------------------------/
-
- CAppleMenu::~CAppleMenu( void )
- {
- menuStruct *ms;
-
- ms = (menuStruct *)findOne( isThis, this, menuList );
- if ( ms ){
- menuList = removeItem( ms , menuList );
- DisposePtr( (Ptr)ms );
- }
-
- sAppleMenu = nil; /* restore */
- appleApplItems = false; /* globals */
-
- SkelRmveMenu( menu );
- }
-
-
- /*---------------------------------------------------------------------*/
- /* TransSkel callbacks for CAppleMenu class */
- /* */
- /* These "C" functions get passed to TransSkel and get */
- /* called at the appropriate events. Except where noted, */
- /* most callbacks defined here merely call the methods */
- /* of the appropriate class instance, though typically, */
- /* these methods will be over-ridden in sub-class definitions. */
- /*---------------------------------------------------------------------*/
-
- extern "C"{
-
- /*---------------------------------------------------------------------*/
- /* _doAppleSelect static */
- /* */
- /* Handle selections in apple menu */
- /* With the current version, this is completely gratuitous */
- /* */
- /* PARAMETERS */
- /* as per TransSkel */
- /* RETURN VALUE */
- /* as per TransSkel */
- /*---------------------------------------------------------------------*/
-
- static pascal void
- _doAppleSelect( short item )
- {
- sAppleMenu->doSelect(item);
- }
-
-
- /*---------------------------------------------------------------------*/
- /* _doAppleClobber static */
- /* */
- /* Free up dynamically allocated menu, if it exists */
- /* */
- /* PARAMETERS */
- /* as per TransSkel */
- /* RETURN VALUE */
- /* as per TransSkel */
- /*---------------------------------------------------------------------*/
-
- static pascal void
- _doAppleClobber( MenuHandle menu )
- {
- if ( menu )
- DisposeMenu( menu );
- }
-
-
- } /* extern "C" */
-
-
-
- //======================================================================/
- // The CWindow Class /
- // /
- // Base Class: CApplObj Class /
- // Methods: • doMouseClick(Point where, long when, short modifiers);/
- // Handle mouse clicks in window /
- // • doKeyClick(short c, short code, short modifiers); /
- // Handle key clicks in window /
- // • doUpdate(Boolean resized); /
- // Handle Update events in window /
- // • doActivate(Boolean active); /
- // Handle Activate events in window /
- // • doClose(void); /
- // Handle closing window (default method /
- // hides window via HideWindow()) /
- // • doIdle(void); /
- // Handle idle events in window /
- // • doShow(void); /
- // Display window (Calls Show/SelectWindow()) /
- // • GetWindowPtr(void); /
- // Returns WindowPtr to QD window struct /
- // /
- // Member variables: /
- // • WindowPtr wind; (protected) /
- // A pointer to the QD window structure /
- // /
- // Description: The CWindow class is the base class for all window /
- // objects in TransSkel++. Users will typically create subclasses /
- // of the CWindow class (e.g., CDrawWindow, CStatusWindow, etc.) /
- // and override any of the above methods and/or create new ones. /
- //======================================================================/
-
-
- //----------------------------------------------------------------------/
- // CWindow public /
- // /
- // The CWindow constructor. /
- // /
- // PARAMETERS /
- // wStorage /
- // boundsRect /
- // tile /
- // visible /
- // procID /
- // behind as per IM:ToolBox Essentials /
- // goAway /
- // refCon /
- // frontIdle Call idle event proc only if frontmost /
- // RETURN VALUE /
- // none /
- //----------------------------------------------------------------------/
-
- CWindow::CWindow( Ptr wStorage,
- Rect *boundsRect,
- Str255 title,
- Boolean visible,
- int procID,
- WindowPtr behind,
- Boolean goAway,
- long refCon,
- Boolean frontIdle )
- {
- SkelppWindowProperty **p;
-
- if ( SkelQuery( skelQHasColorQD ) ){
- wind = NewCWindow( wStorage, boundsRect, title, visible,
- procID, behind, goAway, refCon );
- }
- else{
- wind = NewWindow( wStorage, boundsRect, title, visible,
- procID, behind, goAway, refCon);
- }
-
- if ( !wind ){
- Error( "\pCould not allocate memory for wind",
- Skelpp_fatalErr );
- return;
- }
-
- if ( !SkelWindow ( wind,
- _doWindowMouseClick, /* mouse click handler */
- _doWindowKeyClick, /* key click handler */
- _doWindowUpdate, /* update event handler */
- _doWindowActivate, /* activate event handler */
- _doWindowClose, /* close box click handler */
- nil, /* disposal function */
- _doWindowIdle, /* idle-time handler */
- frontIdle ) /* idle only when frontmost */
- ){
- Error( "\pCould not register wind with TransSkel",
- Skelpp_fatalErr );
- DisposeWindow( wind );
- return;
- }
-
- // Create a SkelppWindowProperty and place a handle to it on the
- // property list of the new window, indexed by SkelppWindowPropertyID
- if ( !(p = (SkelppWindowProperty **)
- NewHandle( sizeof( SkelppWindowProperty ) )) ){
- Error( "\pCould not allocate memory for window property",
- Skelpp_fatalErr );
- SkelRmveWind( wind );
- DisposeWindow( wind );
- return;
- }
-
- (**p).obj = this;
- if ( !SkelAddWindProp( wind, SkelppWindowPropertyID, (long)p ) ){
- Error( "\pCould not put Skel++ window property on property list",
- Skelpp_fatalErr );
- SkelRmveWind( wind );
- DisposeWindow( wind );
- return;
- }
- }
-
-
- //----------------------------------------------------------------------/
- // CWindow public /
- // /
- // The CWindow constructor. /
- // /
- // PARAMETERS /
- // windID /
- // wStorage /
- // behind as per IM:ToolBox Essentials /
- // frontIdle Call idle event proc only if frontmost /
- // RETURN VALUE /
- // none /
- //----------------------------------------------------------------------/
-
- CWindow::CWindow( short windID,
- Ptr wStorage,
- WindowPtr behind,
- Boolean frontIdle )
- {
- SkelppWindowProperty **p;
-
- if ( SkelQuery( skelQHasColorQD ) ){
- wind = GetNewCWindow( windID, wStorage, behind );
- }
- else{
- wind = GetNewCWindow( windID, wStorage, behind );
- }
-
- if ( !wind ){
- Error( "\pCould not allocate memory for wind",
- Skelpp_fatalErr );
- return;
- }
-
- if ( !SkelWindow ( wind,
- _doWindowMouseClick, /* mouse click handler */
- _doWindowKeyClick, /* key click handler */
- _doWindowUpdate, /* update event handler */
- _doWindowActivate, /* activate event handler */
- _doWindowClose, /* close box click handler */
- nil, /* disposal function */
- _doWindowIdle, /* idle-time handler */
- frontIdle ) /* idle only when frontmost */
- ){
- Error( "\pCould not register wind with TransSkel",
- Skelpp_fatalErr );
- DisposeWindow( wind );
- return;
- }
-
- // Create a SkelppWindowProperty and place a handle to it on the
- // property list of the new window, indexed by SkelppWindowPropertyID
- if ( !(p = (SkelppWindowProperty **)
- NewHandle( sizeof( SkelppWindowProperty ) )) ){
- Error( "\pCould not allocate memory for window property",
- Skelpp_fatalErr );
- SkelRmveWind( wind );
- DisposeWindow( wind );
- return;
- }
-
- (**p).obj = this;
- if ( !SkelAddWindProp( wind, SkelppWindowPropertyID, (long)p ) ){
- Error( "\pCould not put Skel++ window property on property list",
- Skelpp_fatalErr );
- SkelRmveWind( wind );
- DisposeWindow( wind );
- return;
- }
- }
-
-
- //----------------------------------------------------------------------/
- // ~CWindow public /
- // /
- // The CWindow destructor. /
- // /
- // PARAMETERS /
- // none /
- // RETURN VALUE /
- // none /
- //----------------------------------------------------------------------/
-
- CWindow::~CWindow( void )
- {
- SkelppWindowProperty **p;
-
- if ( wind ){
- p = (SkelppWindowProperty **)
- SkelGetWindPropData( wind, SkelppWindowPropertyID );
- SkelRmveWindProp( wind, SkelppWindowPropertyID );
- DisposeHandle( (Handle)p );
- SkelRmveWind( wind );
- DisposeWindow( wind );
- }
- }
-
-
- //----------------------------------------------------------------------/
- // doShow protected /
- // /
- // Default doShow method /
- // /
- // PARAMETERS /
- // none /
- // RETURN VALUE /
- // none /
- //----------------------------------------------------------------------/
-
- void
- CWindow::doShow( void )
- {
- ShowWindow( wind );
- SelectWindow( wind );
- }
-
-
-
- //----------------------------------------------------------------------/
- // GetCWindow /
- // /
- // returns a pointer to the class instance associated with wind /
- // /
- // PARAMETERS /
- // wind: a WindowPtr /
- // RETURN VALUE /
- // pointer to CWindow instance associated with wind, if it /
- // exists; nil o/w /
- //----------------------------------------------------------------------/
-
- CWindow *
- GetCWindow( WindowPtr wind )
- {
- SkelppWindowProperty **p = nil;
-
- if ( wind ){
- p = (SkelppWindowProperty **)
- SkelGetWindPropData( wind, SkelppWindowPropertyID );
- }
- return( p ? (CWindow *)((**p).obj) : nil );
- }
-
-
- /*---------------------------------------------------------------------*/
- /* TransSkel callbacks for CWindow class */
- /* */
- /* These "C" functions get passed to TransSkel and get */
- /* called at the appropriate events. Except where noted, */
- /* most callbacks defined here merely call the methods */
- /* of the appropriate class instance, though typically, */
- /* these methods will be over-ridden in sub-class definitions. */
- /*---------------------------------------------------------------------*/
-
- extern "C" {
-
- /*---------------------------------------------------------------------*/
- /* _doWindowMouseClick static */
- /* */
- /* Handle mouseclicks in window */
- /* Calls corresponding class instance's doMouseClick method. */
- /* */
- /* PARAMETERS */
- /* as per TransSkel */
- /* RETURN VALUE */
- /* as per TransSkel */
- /*---------------------------------------------------------------------*/
-
- static pascal void
- _doWindowMouseClick( Point where, long when, short modifiers )
- {
- WindowPtr wind;
- CWindow *w;
-
- GetPort(&wind);
- if ( wind && (w = GetCWindow( wind )) ){
- w->doMouseClick( where, when, modifiers );
- }
- }
-
-
- /*---------------------------------------------------------------------*/
- /* _doWindowKeyClick static */
- /* */
- /* Handle keyclicks in window */
- /* Calls corresponding class instance's doKeyClick method. */
- /* */
- /* PARAMETERS */
- /* as per TransSkel */
- /* RETURN VALUE */
- /* as per TransSkel */
- /*---------------------------------------------------------------------*/
-
- static pascal void
- _doWindowKeyClick( short c, short code, short modifiers )
- {
- WindowPtr wind;
- CWindow *w;
-
- GetPort(&wind);
- if ( w = GetCWindow( wind ) ){
- w->doKeyClick( c, code, modifiers );
- }
- }
-
-
- /*---------------------------------------------------------------------*/
- /* _doWindowUpdate static */
- /* */
- /* Handle window updates */
- /* Calls corresponding class instance's doUpdate method. */
- /* */
- /* PARAMETERS */
- /* as per TransSkel */
- /* RETURN VALUE */
- /* as per TransSkel */
- /*---------------------------------------------------------------------*/
-
- static pascal void
- _doWindowUpdate( Boolean resized )
- {
- WindowPtr wind;
- CWindow *w;
-
- GetPort( &wind );
- if ( w = GetCWindow( wind ) ){
- w->doUpdate( resized );
- }
- }
-
-
- /*---------------------------------------------------------------------*/
- /* _doWindowActivate static */
- /* */
- /* Handle window activates */
- /* Calls corresponding class instance's doActivate method. */
- /* */
- /* PARAMETERS */
- /* as per TransSkel */
- /* RETURN VALUE */
- /* as per TransSkel */
- /*---------------------------------------------------------------------*/
-
- static pascal void
- _doWindowActivate ( Boolean active )
- {
- WindowPtr wind;
- CWindow *w;
-
- GetPort( &wind );
- if ( w = GetCWindow( wind ) ){
- w->doActivate( active );
- }
- }
-
-
- /*---------------------------------------------------------------------*/
- /* _doWindowClose static */
- /* */
- /* Handle closebox selections */
- /* Calls corresponding class instance's doClose method. */
- /* */
- /* PARAMETERS */
- /* as per TransSkel */
- /* RETURN VALUE */
- /* as per TransSkel */
- /*---------------------------------------------------------------------*/
-
- static pascal void
- _doWindowClose( void )
- {
- WindowPtr wind;
- CWindow *w;
-
- GetPort( &wind );
- if ( w = GetCWindow( wind ) ){
- w->doClose();
- }
- }
-
-
- /*---------------------------------------------------------------------*/
- /* _doWindowIdle static */
- /* */
- /* Handle idle events in window */
- /* Calls corresponding class instance's doIdle method. */
- /* */
- /* PARAMETERS */
- /* as per TransSkel */
- /* RETURN VALUE */
- /* as per TransSkel */
- /*---------------------------------------------------------------------*/
-
- static pascal void
- _doWindowIdle( void )
- {
- WindowPtr wind;
- CWindow *w;
-
- GetPort( &wind );
- if ( w = GetCWindow( wind ) ){
- w->doIdle();
- }
- }
-
- } /* extern "C" */
-
-
- //======================================================================/
- // The CDialog Class /
- // /
- // Base Class: CApplObj Class /
- // Methods: • doFilter(EventRecord *evt, short *item); /
- // dialog filter proc /
- // • doSelect(short item); /
- // Handle item selections in dialog /
- // • doClose(void); /
- // Handle closing dialog (default method /
- // hides window via HideWindow()) /
- // • doShow(void); /
- // Display dialog (Calls Show/SelectWindow()) /
- // • GetDialogPtr(void); /
- // Returns DialogPtr to QD dialog struct /
- // /
- // Member variables: /
- // • DialogPtr dlog; (protected) /
- // A pointer to the QD dialog structure /
- // /
- // Description: The CDialog class is the base class for all dialog /
- // objects in TransSkel++. Users will typically create subclasses /
- // of the CDialog class (e.g., CAboutDialog, CSettingDialog, etc.) /
- // and override any of the above methods and/or create new ones. /
- //======================================================================/
-
-
- //----------------------------------------------------------------------/
- // CDialog public /
- // /
- // The CDialog constructor. /
- // /
- // PARAMETERS /
- // dStorage /
- // boundsRect /
- // title /
- // visible /
- // procID /
- // behind as per IM:ToolBox Essentials /
- // goAway /
- // refCon /
- // items /
- // RETURN VALUE /
- // none /
- //----------------------------------------------------------------------/
-
- CDialog::CDialog( Ptr dStorage,
- Rect *boundsRect,
- Str255 title,
- Boolean visible,
- int procID,
- DialogPtr behind,
- Boolean goAway,
- long refCon,
- Handle items )
- {
- SkelppWindowProperty **p;
-
- if ( SkelQuery( skelQHasColorQD ) ){
- dlog = NewCDialog( dStorage, boundsRect, title, visible,
- procID, behind, goAway, refCon, items );
- }
- else{
- dlog = NewDialog( dStorage, boundsRect, title, visible,
- procID, behind, goAway, refCon, items);
- }
-
- if ( !dlog ){
- Error( "\pCould not allocate memory for dlog",
- Skelpp_fatalErr );
- return;
- }
-
- if ( !SkelDialog ( dlog, /* dialog pointer */
- _doDialogFilter, /* filterproc */
- _doDialogSelect, /* item handler */
- _doDialogClose, /* close handler */
- nil ) /* dispose dlog */
- ){
- Error( "\pCould not register dlog with TransSkel",
- Skelpp_fatalErr );
- DisposeWindow( dlog );
- return;
- }
-
- // Create a SkelppWindowProperty and place a handle to it on the
- // property list of the new window, indexed by SkelppWindowPropertyID
- if ( !(p = (SkelppWindowProperty **)
- NewHandle( sizeof( SkelppWindowProperty ) )) ){
- Error( "\pCould not allocate memory for window property",
- Skelpp_fatalErr );
- SkelRmveDlog( dlog );
- DisposeDialog( dlog );
- return;
- }
-
- (**p).obj = this;
- if ( !SkelAddWindProp( dlog, SkelppWindowPropertyID, (long)p ) ){
- Error( "\pCould not put Skel++ window property on property list",
- Skelpp_fatalErr );
- SkelRmveDlog( dlog );
- DisposeDialog( dlog );
- return;
- }
- }
-
-
- //----------------------------------------------------------------------/
- // CDialog public /
- // /
- // The CDialog constructor. /
- // /
- // PARAMETERS /
- // windID /
- // wStorage /
- // behind as per IM:ToolBox Essentials /
- // RETURN VALUE /
- // none /
- //----------------------------------------------------------------------/
-
- CDialog::CDialog(short dlogID, Ptr wStorage, WindowPtr behind)
- {
- SkelppWindowProperty **p;
-
- // No GetNewCDialog ...
- dlog = GetNewDialog( dlogID, wStorage, behind );
-
- if ( !dlog ){
- Error( "\pCould not allocate memory for dlog",
- Skelpp_fatalErr);
- return;
- }
-
- if ( !SkelDialog ( dlog, /* dialog pointer */
- _doDialogFilter, /* filterproc */
- _doDialogSelect, /* item handler */
- _doDialogClose, /* close handler */
- nil ) /* dispose dlog */
- ){
- Error( "\pCould not register dlog with TransSkel",
- Skelpp_fatalErr );
- DisposeWindow( dlog );
- return;
- }
-
- // Create a SkelppWindowProperty and place a handle to it on the
- // property list of the new window, indexed by SkelppWindowPropertyID
- if ( !(p = (SkelppWindowProperty **)
- NewHandle( sizeof( SkelppWindowProperty ) )) ){
- Error( "\pCould not allocate memory for window property",
- Skelpp_fatalErr );
- SkelRmveDlog( dlog );
- DisposeDialog( dlog );
- return;
- }
-
- (**p).obj = this;
- if ( !SkelAddWindProp( dlog, SkelppWindowPropertyID, (long)p ) ){
- Error( "\pCould not put Skel++ window property on property list",
- Skelpp_fatalErr );
- SkelRmveDlog( dlog );
- DisposeDialog( dlog );
- return;
- }
- }
-
-
- //----------------------------------------------------------------------/
- //~ CDialog public /
- // /
- // The CDialog constructor. /
- // Call SkelRmveDlog, which deletes the TransSkel internal /
- // dialog handler, and then calls the clobber /
- // proc for the dlog, which in this case will be _doDialogClobber /
- // (which frees space tied up by dlog). This is safe, /
- // assuming the user has not called SkelRmveDlog or SkelCleanup /
- // _before_ deleting the dlog instance. /
- // /
- // PARAMETERS /
- // none /
- // RETURN VALUE /
- // none /
- //----------------------------------------------------------------------/
-
- CDialog::~CDialog( void )
- {
- SkelppWindowProperty **p;
-
- if ( dlog ){
- p = (SkelppWindowProperty **)
- SkelGetWindPropData( dlog, SkelppWindowPropertyID );
- SkelRmveWindProp( dlog, SkelppWindowPropertyID );
- DisposeHandle( (Handle)p );
- SkelRmveDlog( dlog );
- DisposeDialog( dlog );
- }
- }
-
-
- //----------------------------------------------------------------------/
- // doShow protected /
- // /
- // Default doShow method /
- // /
- // PARAMETERS /
- // none /
- // RETURN VALUE /
- // none /
- //----------------------------------------------------------------------/
-
- void
- CDialog::doShow(void)
- {
- ShowWindow(dlog);
- SelectWindow(dlog);
- }
-
-
- //----------------------------------------------------------------------/
- // GetCDialog /
- // /
- // returns a pointer to the class instance associated with dlog /
- // /
- // PARAMETERS /
- // dlog: a DialogPtr /
- // RETURN VALUE /
- // pointer to CDialog instance associated with dlog, if it /
- // exists; nil o/w /
- //----------------------------------------------------------------------/
-
- CDialog *
- GetCDialog( DialogPtr dlog )
- {
- SkelppWindowProperty **p = nil;
-
- if ( dlog ){
- p = (SkelppWindowProperty **)
- SkelGetWindPropData( dlog, SkelppWindowPropertyID );
- }
- return( p ? (CDialog *)(**p).obj : nil );
- }
-
-
- /*---------------------------------------------------------------------*/
- /* TransSkel callbacks for CDialog class */
- /* */
- /* These "C" functions get passed to TransSkel and get */
- /* called at the appropriate events. Except where noted, */
- /* most callbacks defined here merely call the methods */
- /* of the appropriate class instance, though typically, */
- /* these methods will be over-ridden in sub-class definitions. */
- /*---------------------------------------------------------------------*/
-
- extern "C" {
-
- /*---------------------------------------------------------------------*/
- /* _doDialogFilter static */
- /* */
- /* The dialog's filter proc */
- /* Calls corresponding class instance's doFilter method. */
- /* */
- /* PARAMETERS */
- /* as per TransSkel */
- /* RETURN VALUE */
- /* as per TransSkel */
- /*---------------------------------------------------------------------*/
-
- static pascal Boolean
- _doDialogFilter(DialogPtr dlog, EventRecord *evt, short *item)
- {
- CDialog *d;
- Boolean b = false;
-
- if ( d = GetCDialog( dlog ) ){
- b = d->doFilter( evt, item );
- }
-
- return b;
- }
-
-
- /*---------------------------------------------------------------------*/
- /* _doDialogSelect static */
- /* */
- /* The dialog's item selection proc */
- /* Calls corresponding class instance's doSelect method. */
- /* */
- /* PARAMETERS */
- /* as per TransSkel */
- /* RETURN VALUE */
- /* as per TransSkel */
- /*---------------------------------------------------------------------*/
-
- static pascal void
- _doDialogSelect( DialogPtr dlog, short item )
- {
- CDialog *d;
-
- if ( d = GetCDialog( dlog ) ){
- d->doSelect( item );
- }
- }
-
-
- /*---------------------------------------------------------------------*/
- /* _doDialogClose static */
- /* */
- /* The dialog's item close proc */
- /* Calls corresponding class instance's doClose method. */
- /* */
- /* PARAMETERS */
- /* as per TransSkel */
- /* RETURN VALUE */
- /* as per TransSkel */
- /*---------------------------------------------------------------------*/
-
- static pascal void
- _doDialogClose( void )
- {
- CDialog *d;
- DialogPtr dlog;
-
- GetPort( &dlog );
- if ( d = GetCDialog( dlog ) ){
- d->doClose();
- }
- }
-
- } /* extern "C" */
-
-
- //----------------------------------------------------------------------/
- // /
- // List Handler /
- // /
- // This mini list handler creates dynamic lists using traditional /
- // cons cells which point to (perhaps) dynamically allocated /
- // data objects. For the most part, lists are assumed to be /
- // flat (no nested lists), and the cdr of last cons cell in the list /
- // is assumed to point to nil. OK as long as cons(itemn, nil) is /
- // called first. /
- // /
- // list -->+---+---+ +---+---+ +---+-+ /
- // | o | o---->| o | o----> ... --->| o |\| /
- // +-|-+---+ +-|-+---+ +-|-+-+ /
- // v v v /
- // item1 item2 itemn /
- // /
- // The following functions provide a minimal set of routines /
- // for handling the static menuList which keeps track of which /
- // menus have been defined in TransSkel++. Based on Fred's /
- // List Manager. Supports: /
- // • list cons(elt head, elt tail); /
- // Returns the cons of head and tail, as a consCell. /
- // It is the user's responsibility to destroy cell. /
- // • elt findOne(predPtr pred, void * predParams, list l); /
- // Find first item in list which satisfies pred(predParams) /
- // • list removeItem(elt item, list l); /
- // Remove consCell in list which points to item. /
- // • void DestroyCons(consCell * c); /
- // Deallocate consCell (assuming created via cons) /
- // Leaves item pointed to by cons intact. /
- // • void DestroyList(list l); /
- // Deallocate all consCells in list (assuming created /
- // via cons) Leaves items pointed to by cons' intact. /
- //----------------------------------------------------------------------/
-
-
- //----------------------------------------------------------------------/
- // cons static /
- // /
- // returns -->+---+---+ /
- // | o | o----> tail /
- // +-|-+---+ /
- // v /
- // head /
- // /
- // PARAMETERS /
- // head /
- // tail /
- // RETURN VALUE /
- // new list with head in position 1 /
- //----------------------------------------------------------------------/
-
- static list
- cons( elt head, elt tail )
- {
- list newCell;
-
- if ( !(newCell = (list)NewPtr( sizeof( consCell ) )) ){
- return nil;
- }
-
- car(newCell) = head;
- cdr(newCell) = (consCell *)tail;
-
- return newCell;
- }
-
-
- //----------------------------------------------------------------------/
- // findOne static /
- // /
- // returns a pointer to first element in l statisfying predicate pred; /
- // nil if none found. /
- // /
- // PARAMETERS /
- // pred: predicate to apply to elts in list /
- // predParams: parameter passed to pred /
- // l: list in which to search /
- // RETURN VALUE /
- // new list with head in position 1 /
- //----------------------------------------------------------------------/
-
- static elt
- findOne( predPtr pred, void * predParams, list l )
- {
- Boolean found = false;
-
- /*
- * short circuit evaluation
- */
- while ( l && !(found = (*pred)( car(l), predParams )) ){
- l = cdr(l);
- }
-
- return (found ? car(l) : nil);
- }
-
-
- //----------------------------------------------------------------------/
- // removeItem static /
- // /
- // removes item from list (destructive). Returns pointer to the /
- // orginal list. /
- // /
- // PARAMETERS /
- // item: item to be removed /
- // l: list from which to remove item /
- // RETURN VALUE /
- // new list with item removed; old list if item not in list /
- //----------------------------------------------------------------------/
-
- static list
- removeItem( elt item, list l )
- {
- Boolean found = false;
- list prev = nil, origList = l;
-
- /*
- * short circuit evaluation
- */
- while ( l && !(found = (item == car(l))) ){
- prev = l;
- l = cdr(l);
- }
-
- if ( found ){
- /* l is non-nil */
- if ( prev ){
- if ( cdr(l) ){ /* l is in middle of list */
- cdr(prev) = cdr(l);
- }
- else{ /* l is last item in list */
- cdr(prev) = nil;
- }
- }
- else{ /* l is first item in list */
- origList = cdr(l);
- }
- DestroyCons( l );
- }
-
- return origList;
- }
-
-
- //----------------------------------------------------------------------/
- // DestroyCons static /
- // /
- // Deallocates memory for consCell c / /
- // /
- // PARAMETERS /
- // c: cons cell to be destroyed /
- // RETURN VALUE /
- // none /
- //----------------------------------------------------------------------/
-
- static void
- DestroyCons( consCell * c )
- {
- if ( c )
- DisposePtr( (Ptr)c );
- }
-
-
- //----------------------------------------------------------------------/
- // DestroyList static /
- // /
- // Deallocates memory for each consCell in List / /
- // /
- // PARAMETERS /
- // l: list to be destroyed /
- // RETURN VALUE /
- // none /
- //----------------------------------------------------------------------/
- static void
- DestroyList( list l )
- {
- list tmpList;
-
-
- while ( l ){
- tmpList = (list)cdr(l);
- DestroyCons( l );
- l = tmpList;
- }
- }
-